package com.abc.scholarship.controller;


import com.abc.scholarship.config.security.redis.RedisService;
import com.abc.scholarship.config.security.utils.JwtUtils;
import com.abc.scholarship.config.security.utils.MenuTree;
import com.abc.scholarship.domain.dto.UserInfoDto;
import com.abc.scholarship.domain.entity.Menu;
import com.abc.scholarship.domain.entity.User;
import com.abc.scholarship.domain.vo.resp.ApiResult;
import com.abc.scholarship.domain.vo.resp.RouterVo;
import com.abc.scholarship.domain.vo.resp.TokenVo;
import io.jsonwebtoken.Jwts;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/sysUser")
public class SysUserController {

    @Resource
    private RedisService redisService;

    @Resource
    private JwtUtils jwtUtils;

    /**
     * 刷新token
     *
     * @param request
     * @return
     */
    @PostMapping("/refreshToken")
    public ApiResult refreshToken(HttpServletRequest request) {
        // 从header中获取前端提交的token
        String token = request.getHeader("token");
        // 如果header中没有token，则从参数中获取
        if (ObjectUtils.isEmpty(token)) {
            token = request.getParameter("token");
        }
        // 从Spring security 上下文中获取用户信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

        // 获取身份信息
        UserDetails details = (UserDetails) authentication.getPrincipal();

        //重新生成token
        String reToken = "";
        // 验证原来的token是否合法
        if (jwtUtils.validateToken(token, details)) {
            // 生成新的token
            reToken = jwtUtils.refreshToken(token);
        }
        // 获取原来的token到期时间，交给前端判断
        long expireTime = Jwts.parser().setSigningKey(jwtUtils.getSecret())
                .parseClaimsJws(reToken.replace("jwt_", ""))
                .getBody().getExpiration().getTime();
        // 清除原来的token信息
        String oldToken = "token_" + token;
        redisService.del(oldToken);
        //存储新的token
        String newToken = "token_" + reToken;
        redisService.set(newToken, reToken, jwtUtils.getExpiration() / 1000);

        TokenVo tokenVo = new TokenVo(expireTime, reToken);
        return ApiResult.success(tokenVo);
    }

    /**获取用户信息
     *
     * @return
     */
    @GetMapping("/getInfo")
    public ApiResult getInfo() {
        // 从Spring Security 上下文中获取用户信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        // 判断 authentication 对象是否为空
        if (authentication == null) {
            return ApiResult.fail("用户信息查询失败");
        }

        // 获取用户信息
        User user =  (User)authentication.getPrincipal();
        // 用户权限集合
        List<Menu> permissionList = user.getMenuList();
        // 获取角色权限编码字段
        Object[] roles = permissionList.stream()
                .filter(Objects::nonNull)
                .map(Menu::getCode).toArray();
        // 创建用户信息对象
        UserInfoDto userInfo = new UserInfoDto(user.getId(), user.getUName(), user.getAvatar(), null, user.getRoleId(),roles);

        return ApiResult.success(userInfo);
    }


    /**获取菜单列表
     *
     * @return
     */
    @GetMapping("/getMenuList")
    public ApiResult getMenuList(){
        // 从Spring security 上下文获取用户信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        // 获取用户信息
        User user = (User)authentication.getPrincipal();
        // 获取权限列表
        List<Menu> permissionList = user.getMenuList();
        // 筛选菜单和目录
        List<Menu> collect  =permissionList.stream()
                .filter(item -> item !=null && item.getType() !=2)
                .collect(Collectors.toList());
        // 生成路由数据
        List<RouterVo> routerList = MenuTree.makeRouter(collect, 0L);
        //  返回 数据
        return ApiResult.success(routerList);
    }

    /**退出登录
     *
     * @param request
     * @param response
     * @return
     */
    @PostMapping("/logout")
    public ApiResult logout(HttpServletRequest request, HttpServletResponse response){
        // 获取token
        String token  = request.getParameter("token");
        // 如果没有从头部获取 token ，就从参数中获取
        if(ObjectUtils.isEmpty(token)){
            token = request.getHeader("token");
        }
        // 获取用户相关信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if(authentication  !=null){
            // 清空用户信息
            new SecurityContextLogoutHandler().logout(request,response,authentication);
            // 清空redis 里面的token
            String key  = "token_" +token;
            redisService.del(key);
        }
        return ApiResult.success();
    }
}
